# pragma once
# include <iostream>

typedef struct node{
    struct node* _prev;
    struct node* _next;
    int _val;

    node(int val) {
        _val = val;
        _prev = nullptr;
        _next = nullptr;
    }
}node;

class list{
public:
    list()
    :_head(new node(0))
    ,_tail(new node(0))
    ,_size(0)
    {
        _head->_next = _tail;
        _tail->_prev = _head;
        _head->_prev = _tail;
        _tail->_next = _head;
    }

    int insert_back(int val){
        node *new_node = new node(val);
        _tail->_prev->_next = new_node;
        new_node->_prev = _tail->_prev;
        new_node->_next = _tail;
        _tail->_prev = new_node;
        _size++;
        return _size;
    }

    int insert_head(int val){
        node *new_node = new node(val);
        node *next = _head->_next;
        _head->_next = new_node;
        new_node->_prev = _head;
        new_node->_next = next;
        next->_prev = new_node;
        _size++;
        return _size;
    }

    int delete_back(){
        if (_size > 0){
            node *need_delete = _tail->_prev;
            need_delete->_prev->_next = need_delete->_next;
            need_delete->_next->_prev = need_delete->_prev;
            delete(need_delete);
            _size--;
        }
        return _size;
    }

    int delete_head(){
        if (_size > 0){
            node *need_delete = _head->_next;
            need_delete->_next->_prev = need_delete->_prev;
            need_delete->_prev->_next = need_delete->_next;
            delete(need_delete);
            _size--;
        }
        return _size;
    }

    size_t get_length(){
        return _size;
    }

    bool rdisplay(){
        std::cout<<"tail->";
        if (_size > 0){
            for(node* rpcur = _tail->_prev; rpcur != _head; rpcur = rpcur->_prev)
            {
                std::cout<<rpcur->_val<<"->";
            }
        }
        std::cout<<"head"<<std::endl;
    }

    bool inlist(int val){
        for(node* rpcur = _tail->_prev; rpcur != _head; rpcur = rpcur->_prev)
        {
            if (rpcur->_val == val)
            {
                return true;
            }
        }
        return false;
    }

    void display(){
        std::cout<<"head->";
        for(node* pcur = _head->_next; pcur != _tail; pcur = pcur->_next){
            std::cout<<pcur->_val<<"->";
        }
        std::cout<<"tail"<<std::endl;
    }

    ~list(){
        node* pcur = _head;
        node* pnext = pcur->_next;
        int loop_cnt = 0;
        while (pcur && loop_cnt < _size+2)
        {
            std::cout<<"in ~list()"<<pcur->_val<<std::endl;
            delete(pcur);
            pcur = pnext;
            if(pcur)
                pnext = pcur->_next;
            loop_cnt++;
        }
        _size = 0;
    }

private:
    struct node* _head;
    struct node* _tail;
    int _size;
};

